home *** CD-ROM | disk | FTP | other *** search
- {$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}
- {$M 64384,0,655360}
- Uses VgaGraph, Crt;
-
- Const
- RandInit : LongInt = 10;
- MaxCol = 190; { Last Color }
- MinCol = 1; { First Color }
- XMax = 319;
- XHalf = XMax shr 1;
- YMax = 199;
- YHalf = YMax shr 1;
- Roughness : Real = 10.0; { Default roughness }
- FadeOut : Real = 1.0; { Default fade value }
- XAspect = 1.2; { Aspect Ratio }
- YAspect = 1.0;
- Radii : Integer = 32;
- XRadii : Integer = 38;
- YRadii : Integer = 32;
-
- Var
- ArcSinTab : Array[-90..90] of Real; { -1 to +1 }
- ArcCosTab : Array[0..180] of Real; { +1 to -1 }
- Aspects : Boolean; { Use Square or Aspect? }
- Nat_Plasm : Boolean; { Totally random? }
- Centre : Boolean; { Is the center random as well? }
- PalDelay : Word;
-
- Procedure PrepPalette;
- { Prepares the first VGA palette (fire like) }
- var
- b : Byte;
- begin
- SetRGBPalette( 0, 0, 0, 0 );
- For b := 0 to 63 do
- SetRGBPalette( b+1, b, 0, 0 );
- For b := 1 to 63 do
- SetRGBPalette( b+64, 63, b, 0 );
- For b := 1 to 63 do
- SetRGBPalette( b+127, 63, 63, b );
- SetRGBPalette( 191, 63, 0, 63 );
- For b := 0 to 190 do
- PutPixel( 0, b, b );
- end;
-
- Procedure PrepPal;
- { Prepares the second VGA palette. }
- var
- b : Byte;
- begin
- For b := 0 to 63 do
- SetRGBPalette( b+1, b, 0, 63-b );
- For b := 1 to 63 do
- SetRGBPalette( b+64, 63-b, b, 0 );
- For b := 1 to 63 do
- SetRGBPalette( b+127, 0, 63-b, b );
- end;
-
- Function ArcSin( sn : Real ) : Integer;
- { Returns the ArcSin of an angle. }
- var
- i : Integer;
- last : Real;
- lnum : Integer;
- begin
- lnum := -90;
- last := Abs(sn - ArcSinTab[-90]); { Absolute difference }
- For i := -89 to 90 do
- If Abs(sn-ArcSinTab[i])<last then
- begin
- last := Abs(sn-ArcSinTab[i]);
- lnum := i;
- end;
- ArcSin := lnum;
- end;
-
- Function ArcCos( sn : Real ) : Integer;
- { Returns the ArcCos of an angle. }
- var
- i : Integer;
- last : Real;
- lnum : Integer;
- begin
- lnum := 0;
- last := Abs(sn - ArcCosTab[0]); { Absolute difference }
- For i := 1 to 180 do
- If Abs(sn-ArcCosTab[i])<last then
- begin
- last := Abs(sn-ArcCosTab[i]);
- lnum := i;
- end;
- ArcCos := lnum;
- end;
-
- Function Tan( x : Real ) : Real;
- { Returns a tangent of an angle. }
- begin
- Tan := Sin(x)/Cos(x);
- end;
-
- Function Radians( Ang : Real ) : Real;
- { Converts degrees into radians. }
- begin
- Radians := Ang/180*Pi;
- end;
-
- Function FindX( Ang, Rad : Real ) : Integer;
- { Polar coordinates to cartesian coordinates. }
- var
- Tmp : Integer;
- Tmp2 : Real;
- begin
- If Aspects then
- FindX := Trunc(Cos(Ang/180*Pi)*Rad*XAspect)
- else
- FindX := Trunc(Cos(Ang/180*Pi)*Rad);
- end;
-
- Function FindY( Ang, Rad : Real ) : Integer;
- { Polar coordinates to cartesian coordinates. }
- var
- Tmp : Integer;
- begin
- FindY := Trunc(Sin(Ang/180*Pi)*Rad);
- end;
-
- Function RandOf( Relat : Byte; Len : Real ) : Byte;
- { Adds an amount of randomness to Relat, depending on the distance Len. }
- var
- i : Integer;
- begin
- i := Relat+Random(Trunc(Roughness*Len))-Trunc(Roughness*Len*0.5)-
- Trunc(FadeOut*Len);
- If i < 1 then
- i := 1
- else
- If i > 190 then
- i := 190;
- RandOf := Byte(i);
- end;
-
- Function Distance( x1, y1, x2, y2 : Integer ) : Real;
- { Returns the distance between two points. }
- begin
- Distance := Sqrt( Sqr(x1-x2)+Sqr(y1-y2) );
- end;
-
- Function ChordDist( x1, y1, x2, y2 : Integer; Dist : Real ) : Real;
- { Returns the distance between two points on a chord. }
- begin
- ChordDist := (2*ArcSin( Distance(x1,y1,x2,y2)/(2*Dist) )*Pi*Sqr(Dist))/360;
- end;
-
- Procedure LineOut( x1, y1, x2, y2 : Integer );
- { Creates the initial line axis of the circular plasma. }
- Const
- Sqrt2 = 1.4142135624;
- var
- x3, y3 : Integer;
- begin
- x3 := (x1+x2) div 2; y3 := (y1+y2) div 2;
- If ((x3<>x1) AND (x3<>x2)) OR ((y3<>y1) AND (y3<>y2)) then
- begin
- PutPixel( x3, y3, RandOf( (GetPixel(x1,y1)+GetPixel(x2,y2))div 2,
- Distance( x1, y1, x3, y3 ) ) );
- LineOut( x1, y1, x3, y3 );
- LineOut( x3, y3, x2, y2 );
- end;
- end;
-
- Var
- WorryAng : Real; { Minimum angle that we have to worry about. }
- Quit : Boolean; { Quitin' time. }
-
- Function NearIn( Angle, Radii : Real ) : Byte;
- { Finds out what the nearest pixel at the same angle is equal to. }
- var
- x, y, i : Integer;
- r, Len : Real;
- begin
- r := Radii;
- Repeat
- x := FindX( Angle, r ); y := FindY( Angle, r );
- r := r - Sqrt(2);
- Until GetPixel(x+XHalf,y+YHalf) > 0;
- Len := Distance( FindX(Angle,Radii), FindY(Angle,Radii), x, y );
- Repeat
- i := GetPixel(x+XHalf,y+YHalf)+
- Random(Trunc(Roughness*Len))-Trunc(Roughness*Len*0.5);
- { Trunc(FadeOut*Len);}
- Until (i < 191) AND (i > 0);
- NearIn := Byte(i);
- end;
-
- Procedure RoundOut( Ang1, Ang2, Rad : Real );
- { Interpolates what (Ang1+Ang2)/2, Rad is equal to. }
- var
- Ang3 : Real;
- begin
- If (Abs(Ang1-Ang2) > WorryAng) AND not Quit then
- begin
- Ang3 := (Ang1+Ang2)/2;
- If GetPixel( FindX( Ang3, Rad )+XHalf, FindY( Ang3, Rad )+YHalf ) = 0 then
- begin
- { PutPixel( FindX(Ang3,Rad)+XHalf,FindY(Ang3,Rad)+YHalf, 191 );
- Delay( 10 );
- PutPixel( FindX(Ang3,Rad)+XHalf,FindY(Ang3,Rad)+YHalf, 0 );}
- PutPixel( FindX(Ang3,Rad)+XHalf,FindY(Ang3,Rad)+YHalf,
- ((Integer(RandOf((GetPixel(FindX(Ang1,Rad)+XHalf,
- FindY(Ang1,Rad)+YHalf)+GetPixel(FindX(Ang2,Rad)+XHalf,
- FindY(Ang2,Rad)+YHalf)) shr 1,{Chord}Distance(FindX(Ang1,Rad),
- FindY(Ang1,Rad),FindX(Ang3,Rad),
- FindY(Ang3,Rad){,Rad}))) shl 1)+NearIn( Ang3, Rad )) div 3 );
- end;
- Quit := KeyPressed;
- RoundOut( Ang1, Ang3, Rad );
- RoundOut( Ang3, Ang2, Rad );
- end;
- end;
-
- Procedure Naturalness;
- { Creates a random-based axis. }
- begin
- If Centre then
- PutPixel( XHalf, YHalf, Random(190)+1 )
- else
- PutPixel( XHalf, YHalf, 190 );
- PutPixel( XHalf+XRadii, YHalf, Random(190)+1-Trunc(Radii*FadeOut) );
- PutPixel( XHalf-XRadii, YHalf, Random(190)+1-Trunc(Radii*FadeOut) );
- PutPixel( XHalf, YHalf+YRadii, Random(190)+1-Trunc(Radii*FadeOut) );
- PutPixel( XHalf, YHalf-YRadii, Random(190)+1-Trunc(Radii*FadeOut) );
- end;
-
- Procedure RotatePal;
- { Controls the various palette rotations }
- type
- rgbrec = record r, g, b : Byte; end;
- var
- Pals : Array[0..255] of RgbRec;
- Tmp : RgbRec;
- i, j : Integer;
- begin
- For i := 0 to 255 do
- GetRGBPalette( i, Pals[i].r, Pals[i].g, Pals[i].b );
- Pals[1].r := 0; Pals[1].g := 0; Pals[1].b := 0;
- For i := 1 to 190 do
- SetRGBPalette( i, 0, 0, 0 ); { Blank out palette. }
-
- Repeat { Black, rotate in color, rotate out color, black. }
- For i := 1 to 190 do { Rotate in color }
- begin
- For j := 1 to i do
- SetRGBPalette( 190-i+j, Pals[j].r, Pals[j].g, Pals[j].b );
- Delay( PalDelay );
- end;
- For i := 2 to 190 do { Rotate through color }
- begin
- For j := i to 190 do
- SetRGBPalette( j-i+1, Pals[j-i+1].r, Pals[j-i+1].g, Pals[j-i+1].b );
- SetRGBPalette( 192-i, 0, 0, 0 );
- Delay( PalDelay );
- end;
- For i := 1 to 190 do { Black }
- SetRGBPalette( i, 0, 0, 0 );
- Until UpCase(ReadKey) in ['Q',#27]; { Until the ESC or Q key. }
-
- Repeat { Rotate colors one way... }
- Tmp := Pals[1];
- Move( Pals[2], Pals[1], 189*3 );
- Pals[190] := Tmp;
- For i := 1 to 190 do
- SetRGBPalette( i, Pals[i].r, Pals[i].g, Pals[i].b );
- Delay( PalDelay );
- Until KeyPressed;
- ReadKey;
-
- Repeat { Rotate colors the other way... }
- Tmp := Pals[190];
- Move( Pals[1], Pals[2], 189*3 );
- Pals[1] := Tmp;
- For i := 1 to 190 do
- SetRGBPalette( i, Pals[i].r, Pals[i].g, Pals[i].b );
- Delay( PalDelay );
- Until KeyPressed;
- ReadKey;
-
- PrepPal; { A new palette to play with. }
- For i := 0 to 255 do
- GetRGBPalette( i, Pals[i].r, Pals[i].g, Pals[i].b );
- Repeat { Forward through the colors. }
- Tmp := Pals[1];
- Move( Pals[2], Pals[1], 189*3 );
- Pals[190] := Tmp;
- For i := 1 to 190 do
- SetRGBPalette( i, Pals[i].r, Pals[i].g, Pals[i].b );
- Delay( PalDelay );
- Until KeyPressed;
- ReadKey;
-
- Repeat { Backward through the colors. }
- Tmp := Pals[190];
- Move( Pals[1], Pals[2], 189*3 );
- Pals[1] := Tmp;
- For i := 1 to 190 do
- SetRGBPalette( i, Pals[i].r, Pals[i].g, Pals[i].b );
- Delay( PalDelay );
- Until KeyPressed;
- ReadKey;
-
- ReadKey;
- end;
-
- Procedure Main;
- var
- i : Real;
- s : Real;
- j : Integer;
- begin
- InitGraph;
- PrepPalette;
- SetColor( 191 );
- Line( XHalf+XRadii+1, YHalf+YRadii+1, xHalf+XRadii+1, YHalf-YRadii-1 );
- Line( XHalf+XRadii+1, YHalf+YRadii+1, xHalf-XRadii-1, YHalf+YRadii+1 );
- Line( XHalf-XRadii-1, YHalf-YRadii-1, xHalf+XRadii+1, YHalf-YRadii-1 );
- Line( XHalf-XRadii-1, YHalf-YRadii-1, xHalf-XRadii-1, YHalf+YRadii+1 );
- PutPixel( XHalf, YHalf, 190 );
- If Nat_Plasm then
- Naturalness;
- LineOut( XHalf, YHalf, XHalf+XRadii, YHalf ); { Create plasma axis. }
- LineOut( XHalf, YHalf, XHalf-XRadii, YHalf );
- LineOut( XHalf, YHalf, XHalf, YHalf+YRadii );
- LineOut( XHalf, YHalf, XHalf, YHalf-YRadii );
- s := 0.707106781; { Minimum radius to worry about. }
- Quit := FALSE;
- i := s;
- Repeat
- RoundOut( 0, 90, i ); { Figgle out plasma from x to y degrees, }
- RoundOut( 90, 180, i ); { at radius i }
- RoundOut( 180, 270, i );
- RoundOut( 270, 360, i );
- i := i + s { Radius increases. }
- Until i >= Radii;
- Write(#7); { Beep! }
- ReadKey;
- SetRGBPalette( 0, 0, 0, 63 ); { Show any "missed" spots. }
- Delay( 1000 );
- SetRGBPalette( 0, 0, 0, 0 );
- RotatePal;
- CloseGraph;
- end;
-
- Procedure ReadInput;
- var
- s : String;
- i, e : Integer;
- r : Real;
- c : Char;
- begin
- Writeln;
- Write( 'Enter # for RandSeed, or nothing for random: ' );
- Readln( s );
- Val( s, i, e );
- If (s='') OR (e<>0) then
- Randomize
- else
- Randseed := i;
- Write( 'Roughness value [10.0]: ' );
- Readln( s );
- Val( s, r, e );
- If (s<>'') AND (e=0) then
- Roughness := r;
- Write( 'Radii (in pixels) [32]: ' );
- Readln( s );
- Val( s, i, e );
- If (s<>'') AND (e=0) then
- Radii := i
- else
- Radii := 32;
- If Radii > 100 then
- Radii := 100;
- Write( 'Fadeout Value [0.0]: ' );
- Readln( s );
- Val( s, r, e );
- If (s<>'') AND (e=0) then
- FadeOut := r
- else
- FadeOut := 0.0;
- Write( 'Ejection Angle [0.6]: ' );
- Readln( s );
- Val( s, r, e );
- If (s<>'') AND (e=0) AND (r > 0) then
- WorryAng := r
- else
- WorryAng := 0.6;
- Write( 'Delay in palette rotation (ms) [5]: ' );
- Readln( s );
- Val( s, i, e );
- If (s<>'') AND (e=0) then
- PalDelay := Abs(i)
- else
- PalDelay := 5;
- Write( 'Correct the screen aspect? <Y/N>' );
- Repeat
- C := UpCase( ReadKey );
- Until C in ['Y','N'];
- Aspects := C = 'Y';
- If Aspects then
- begin
- XRadii := Trunc(1.2*Radii);
- YRadii := Radii;
- end
- else
- begin
- XRadii := Radii;
- YRadii := Radii;
- end;
- Write( #13, #10, 'Use random colors for the endpoints? <Y/N>' );
- Repeat
- C := UpCase( ReadKey );
- Until C in ['Y','N'];
- Nat_Plasm := C = 'Y';
- If Nat_Plasm then
- begin
- Write( #13, #10, 'Use a random color for the center? <Y/N>' );
- Repeat
- C := UpCase( ReadKey );
- Until C in ['Y','N'];
- Centre := C = 'Y';
- end;
- end;
-
- Begin
- ReadInput;
- Main;
- End.
-